package ru.spbau.design.snmp.android.viewer.networking;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class NetworkClient implements INetworkClient {

	public InputStream getXML(String ip, int port) throws IOException {

		Socket socket = null;
		//PipedOutputStream out_stream = new PipedOutputStream();
		InputStream result_stream; // = new PipedInputStream(out_stream);

		try {
			socket = new Socket(ip, port);

			String message = getTxMessage();

			socket.getOutputStream().write(getRawSize(message.length()));
			socket.getOutputStream().write(message.getBytes());

			byte[] header = new byte[4];
			socket.getInputStream().read(header);
			int datagramm_size = decodeRawSize(header);
			byte[] data = new byte[datagramm_size];
			int readed = 0;
			while (readed < datagramm_size){
				readed += socket.getInputStream().read(data, readed, datagramm_size - readed);
			}
			
			//System.out.println(new String(data));
			
			System.out.println("Datagram size: " + String.valueOf(datagramm_size));
			
			result_stream = new ByteArrayInputStream(data); //.write(data, 0, data.length);
			
			System.out.println("Stream size: " + result_stream.available());

		} catch (UnknownHostException e) {
			e.printStackTrace();
			throw new IOException("Unknown Host");
		} finally {
			if (socket != null) {
				socket.close();
			}
		}
		return result_stream;
	}

	private static int m_int_size = 4;

	private byte[] getRawSize(int size) {
		byte result[] = new byte[m_int_size];
		for (int i = 0; i < m_int_size; ++i) {
			result[i] = (byte) ((size >> (i * 8)) & 0xFF);
		}
		return result;
		// return new byte[] {
		// (byte)(size >>> 24),
		// (byte)(size >>> 16),
		// (byte)(size >>> 8),
		// (byte)size};
	}

	/* DOES anybody know how to do this correctly? */
	
	private static int HACK(byte b) {
		if (b < 0) {
			return 256 + b;
		} else {
			return b;
		}
	}

	private int decodeRawSize(byte[] header) {
		int result = 0;
		for (int i = 0; i < m_int_size; ++i) {
			int v = (HACK(header[i])) << (i * 8);
			
			//System.out.println(String.valueOf(i) + "th byte value is " + String.valueOf(v));
			
			result += v;
		}
		return result;
		// return (header[0] << 24)
		// + ((header[1] & 0xFF) << 16)
		// + ((header[2] & 0xFF) << 8)
		// + (header[3] & 0xFF);
	}

	private String getTxMessage() {
		return "<request type=\"known-nodes\" answer-port=\"\" />";
		//return "<hello___________000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000__________________________________________________________________________________________________________________________________________________________________________________________________-world!/>";
	}

}
